<template>
  <div class="p-4">
    <ImagePreview :imageList="imgList"></ImagePreview>
    <BasicTable @register="registerTable" :searchInfo="queryParam" @change="tableChange" :rowSelection="rowSelection">
      <template #bodyCell="{ record, column }">
        <template v-if="column.dataIndex === 'fileName'">
          <div class="colFileName">
            <!--名称(文件夹)-->
            <template v-if="record.isDir">
                <a-space>
                  <template v-if="record.directoryType === '3'">
                    <span><FolderOpenFilled style="color: #ffb32b; font-size: 20px;" /></span>
                  </template>
                  <template v-else>
                    <span><FolderOpenFilled style="color: #2878ff; font-size: 20px;" /></span>
                  </template>
                  <template v-if="editableData.directoryName && editableData.dirId === record.dirId">
                    <a-input
                      ref="input_focus"
                      v-model:value="editableData.directoryName"
                      style="margin: -5px 0"
                      @pressEnter="handleEnter"
                      @blur="handleBlur"
                    />
                  </template>
                  <template v-else><span @click="openDir(record)" class="openDir">{{ record.directoryName }}</span></template>
                </a-space>
            </template>
            <!--名称(文件)-->
            <template v-else>
              <a-space>
                <template v-if="editableData.fileName && editableData.fileId === record.fileId">
                    <a-input
                      ref="input_focus"
                      v-model:value="editableData.fileNameNoSuffix"
                      style="margin: -5px 0"
                      @pressEnter="handleEnter"
                      @blur="handleBlur"
                    />
                  </template>
                <template v-else><span @click="visibleModal('openFile', record)" class="openDir">{{ record.fileName }} </span></template>
              </a-space>
            </template>
          </div>
        </template>
        <template v-if="column.dataIndex === 'fileType'">
          <div>
              {{ optionsList.fileType.find(item => item.value && item.value === record.fileType)?.label || '' }}
          </div>
        </template>
      </template>
      <template #toolbar>
        <a-button class="upload" preIcon="ant-design:cloud-upload-outlined" :disabled="!btnAuthTemplate('上传文件')" @click="visibleModal('uploadFile')"> 上传文件 </a-button>
        <a-button class="addButton" preIcon="ant-design:plus-outlined" :disabled="!btnAuthTemplate('新建文件夹')" @click="visibleModal('addDir')"> 新建文件夹 </a-button>
        <a-button class="addButton" preIcon="ant-design:diff-outlined" :disabled="!btnAuthTemplate('移动文件')" @click="visibleModal('moveFile')"> 移动文件 </a-button>
        <a-select style="width: 143px;" v-model:value="queryParam.device" allowClear :options="optionsList.device" @change="value => selectChange('device', value)"></a-select>
        <a-select style="width: 143px;" v-model:value="queryParam.fileType" allowClear :options="optionsList.fileType" @change="value => selectChange('fileType', value)"></a-select>
        <a-date-picker style="width: 143px;" valueFormat="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm:ss"
          @change="getData" @ok="getData" show-time v-model:value="queryParam.createTime" />
      </template>
      <template #tableTop>
        <div class="folderLevelBox">
          <div class="left">当前位置</div>
          <div class="right">
            <div class="rightBox">
              <div class="box" v-for="(item, index) in dirNavigation" :key="index" >
                <div class="img">
                  <FolderOpenFilled style="color: #ffb32b; font-size: 20px;" />
                </div>
                <div class="text openDir" @click="clickDir(index)">{{  item.name }}</div>
                <CaretRightOutlined />
              </div>
            </div>
          </div>
          <a-input-search
            allowClear
            v-model:value="queryParam.fileName"
            placeholder="请输入文件名称"
            style="width: 200px;"
            @search="enterSearch"
          />
        </div>
      </template>
      <template #action="{ record, column }">
        <TableAction :actions="createActions(record, column)" />
      </template>
    </BasicTable>
    <uploadFileModal :dirList="dirNavigation" @success="success" @register="registerUploadFileModal"></uploadFileModal>
    <AddDirModal :dirList="dirNavigation" @success="success" @register="registerAddDir"></AddDirModal>
    <moveFileModal
      :moveType="moveType"
      :dirList="dirNavigation"
      :fileId="curFileId"
      :fileName="curFileName"
      :dirId="curDirId"
      @success="success"
      @register="registerMoveFile"
    ></moveFileModal>
  </div>
</template>
<script lang="ts" setup>
import uploadFileModal from './components/uploadFileModal.vue'
import moveFileModal from './components/moveFileModal.vue';
import AddDirModal from './components/addDirModal.vue';
import { useRoute, useRouter, onBeforeRouteEnter } from 'vue-router';
import { onUnmounted, onMounted, reactive, watch, ref, computed, toRaw, nextTick } from 'vue';
import { BasicTable, useTable, TableAction, EditRecordRow, BasicColumn, ActionItem, } from '/@/components/Table';
import { useMessage } from '/@/hooks/web/useMessage';
import { cloneDeep, template } from 'lodash-es';
import { useModal } from '/@/components/Modal';
import { render } from '/@/utils/common/renderUtils';
import { createImgPreview, ImagePreview } from '/@/components/Preview/index';
import { ImageProps } from '/@/components/Preview/src/typing';
import { useMultipleTabStore } from '/@/store/modules/multipleTab';
import { postList, getDirDictionary, putDirRename, 
  deteleDirDelete, delSingleFile, putRenameFile } from './data.api'
import {
  CaretRightOutlined,
  FolderOpenFilled,
  SearchOutlined
} from '@ant-design/icons-vue';
import { DataDirNavigation, DataTablePagination, ProjectIdCache } from '/@/constants/index'

const router = useRouter()
const route = useRoute()

const tabStore = useMultipleTabStore();
let imgList: ImageProps[] = []
const optionsList = ref({
  device: [{
    value: '',
    label: '全部设备',
  }],
  dirType: [],
  fileType: [{
    value: '',
    label: '全部文件类型',
  }],
})   // 字典数据
const columns:BasicColumn[] = [
  {
    title: '名称',
    dataIndex: 'fileName',
    key: 'fileName',
    align: 'left',
    width: 350,
    ellipsis: true
  },
  {
    title: '文件类型',
    dataIndex: 'fileType',
    key: 'fileType',
    // width: '150px',
    align: 'center',
  },
  {
    title: '拍摄设备',
    dataIndex: 'deviceName',
    key: 'deviceName',
    // width: '150px',
    align: 'center',
    customRender: function ({ text, record }) {
      const { payload } = record as any
      return `${text || ''} ${payload || ''}`
    },
  },
  {
    title: '大小',
    dataIndex: 'fileSize',
    key: 'fileSize',
    width: '120px',
    align: 'center',
    customRender: function ({ record }) {
      const { isDir, dirSize, fileSize } = record as any
      const size = isDir ? dirSize : fileSize
      const isM = size >= (1024 * 1024)
      const isKB = size >= 1024
      const text = size ? isM ? (size  / (1024 * 1024)).toFixed(2) : isKB ? (size  / (1024 )).toFixed(2) : Number(size || 0) ? size.toFixed(2) : 0 : 0
      return `${text}${isM ? 'M' : isKB ? 'KB' : 'B'}`
    },
  },
  {
    title: '创建时间',
    dataIndex: 'createTime',
    key: 'createTime',
    width: '150px',
    align: 'center',
  },
]
const { createMessage , createConfirm } = useMessage();
let queryParam = reactive({
  fileType: '',
  device: '',
  createTime: '',
  fileName: '',
  parentId: '0',
  // pageNo: 1,
  // pageSize: 10
})
//注册table数据
const [registerTable, { getPaginationRef, getDataSource, getSelectRows, reload, setProps }] = useTable({
    title: '数据管理',
    api: postList,
    rowKey: 'id',
    columns: columns,
    searchInfo: {
      parentId: queryParam.parentId
    },
    clickToRowSelect: false,
    striped: true,
    useSearchForm: false,
    showTableSetting: false,
    bordered: true,
    showIndexColumn: false,
    canResize: false,
    showActionColumn: true,
    actionColumn: {
      width: 240,
      title: '操作',
      fixed: 'right',
      dataIndex: 'action',
      slots: { customRender: 'action' },
    },
});
/**
  * 选择列配置
*/
const rowSelection = {
  type: 'checkbox',
  columnWidth: 50,
};
const editableData = ref<any>({});   // 可编辑行数据(修改文件夹名称)
const [registerUploadFileModal, { openModal }] = useModal()
const [registerAddDir, { openModal: addDirModal }] = useModal()
const [registerMoveFile, { openModal: openMoveFile }] = useModal()
// 文件夹导航
const dirNavigation =  ref<any[]>([{
  name: '根目录',
  id: '0',
  dirType: ''  //文件夹类型
}
]);
const moveType = ref<string>("")
// 移动文件/文件夹
let curFileId = ref<string | number>('')
let curFileName = ref<string>('')
let curDirId = ref<string>('')
const input_focus = ref(null);

watch(
  () => router.options.history.state,
  async (newValue,oldValue)=> {
    //const { back, replaced } = newValue
    const curProjectId = localStorage.getItem('Project_Id')
    const projectIdCache = sessionStorage.getItem(ProjectIdCache)
    //console.log('watch路由', curProjectId, projectIdCache)
    if(JSON.stringify(curProjectId) === projectIdCache){
      // 缓存中获取数据的场景： 项目id不变更
      getDirCache()
    }else{
      sessionStorage.setItem(ProjectIdCache, JSON.stringify(curProjectId))  // 更新页面中缓存的项目id
    }
},{  }
)

// 从缓存中获取当前目录的路径
const getDirCache = async () => {
  const dirCache = sessionStorage.getItem(DataDirNavigation)
  const paginationCache = sessionStorage.getItem(DataTablePagination)
  if(dirCache){
    const dirNavigationCache = JSON.parse(dirCache)
    const newParentId = dirNavigationCache[dirNavigationCache?.length - 1]?.id
    //console.log("newParentId", newParentId)
    if(newParentId != queryParam.parentId){
      dirNavigation.value = dirNavigationCache
      queryParam.parentId = newParentId
      // const { current, pageSize } = paginationCache
      // queryParam.pageNo = current
      // queryParam.pageSize = pageSize
      await nextTick()
      searchQuery()
    }
  }
}

onMounted(async () => {
  //console.log("打开数据管理页面--")
  getDirCache()
  const ProjectId = localStorage.getItem('Project_Id')
  sessionStorage.setItem(ProjectIdCache, JSON.stringify(ProjectId))
  // 初始化字典
  const res = await getDirDictionary({})
  //console.log("result", res)
  if(Object.keys(res)?.length){
    Object.keys(res).forEach(key => {
      if(['device', 'dirType', 'fileType'].includes(key)){
        if(['device', 'fileType'].includes(key)){
          optionsList.value[key] = optionsList.value[key].concat(res[key])
        }else{
          optionsList.value[key] = res[key]
        }
      }
    });
  }
});

onUnmounted(()=> {
  const index = getTabsState.value?.length ? getTabsState.value.findIndex( item => item.path === '/dataManage/dataManage') : null
  //console.log('销毁缓存的项目id', index, getTabsState.value)
  if(index === -1 || index === null){
    sessionStorage.setItem(DataDirNavigation, '')  // 切换目录时清空数据管理的目录路径缓存
    sessionStorage.setItem(ProjectIdCache, '')  //tabs中没有当前页签时就销毁缓存的项目id
  }
})

const getTabsState = computed(() => {
  return tabStore.getTabList.filter((item) => !item.meta?.hideTab);
});

const getFileNameLabel = computed(() => {
  (record) => {
    const label = optionsList.value.fileType.find(item => item.value && item.value === record.fileType)?.label || ''
    return label ? render.renderTip(label, 12) : '-'
  }
});

const getCurDirId = computed( ()=>{
  const curDirListTemp = dirNavigation.value
  return curDirListTemp[curDirListTemp?.length - 1]?.id
})

function searchQuery() {
  setProps({ searchInfo: toRaw(queryParam) });
  reload()
}

function getData() {
  searchQuery()
}

function success() {
  searchQuery()
}

const tableChange = (pagination) => {
  const { current, pageSize } = pagination
  // queryParam.pageNo = current
  // queryParam.pageSize = pageSize
}

function visibleModal(type: string, data?: any) {
  switch(type){
    case "uploadFile":
      openModal(true)
      break
    case "addDir":  // 仅仅
      addDirModal(true)
      break
    case "moveFile":   // TODO: 批量移动文件
      {
        const selectRows:any[] = getSelectRows()
        //console.log("selectRows", selectRows)
        if(!selectRows?.length){
          createMessage.warning("请勾选一个文件")
          return
        }
        if(selectRows?.length > 1){
          createMessage.warning("只支持移动单个文件")
          return
        }
        const { isDir, fileId, fileName } = selectRows[0]
        if(isDir){
          createMessage.warning("请勾选文件")
          return
        }
        curFileId.value =  fileId
        curFileName.value = fileName
        moveType.value = 'file'
        openMoveFile(true)
      }
      break
    case "openFile":   // 打开文件详情
      {
        const { fileId } = data
        const pagination = getPaginationRef()
        const { current, pageSize } = pagination
        sessionStorage.setItem(DataTablePagination, JSON.stringify(pagination))
        router.push({
          path: '/dataManage/dataManage/detail', 
          query: { fileId: fileId, dirId: getCurDirId.value, dirPage: current, dirPageSize: pageSize }
        })
      }
      break
  }
}

// 修改文件/文件夹名称(回车)
const handleEnter = (e) => {
  //console.log("回车--e", e.target.value)
  const editData = editableData.value
  const { isDir, dirId, fileId, directoryName, directoryNameCache, fileNameNoSuffix, fileName} = editData
  if(isDir){
    createConfirm({
      title: '修改文件夹名称',
      content: '确定要修改该文件夹名称吗？',
      iconType: 'warning',
      onOk: async () => {
        await putDirRename({ id: dirId, newName: directoryName, oldName: directoryNameCache })
        searchQuery()
      },
      onCancel: () => {},
    });
  }else{
    createConfirm({
      title: '修改文件名称',
      content: '确定要修改该文件名称吗？',
      iconType: 'warning',
      onOk: async () => {
        await putRenameFile({ 
          id: fileId,
          newName: `${fileNameNoSuffix}.${fileName.substring(fileName.lastIndexOf(".") + 1)}`, 
          oldName: fileName
         })
        searchQuery()
      },
      onCancel: () => {},
    });
  }
}

// 变更文件夹名称(失焦)
const handleBlur = (e) => {
  //console.log("失焦--e", e.target.value)
  editableData.value = {}
}

const handleAction = async(type: string, record: EditRecordRow) => {
  //console.log("功能操作--record", record)
  const { isDir, dirId, fileName, fileId, directoryName } = record
  switch(type){
    case '重命名':
      {
        const editDataTemp = {...record}
        if(isDir){
          editDataTemp.directoryNameCache = directoryName
        }else{
          editDataTemp.fileNameNoSuffix = fileName.substring(0, fileName.lastIndexOf("."))
        }
        editableData.value = cloneDeep(editDataTemp);
        setTimeout(() => {
          input_focus.value && input_focus.value.focus();
        }, 10);
      }
    break;
    case '移动':
      {
        if(isDir){
          curDirId.value =  dirId
          moveType.value = 'dir'
        }else{
          curFileId.value =  fileId
          curFileName.value = fileName
          moveType.value = 'file'
        }
        openMoveFile(true)
      }
    break;
    case '删除':
      {
        if(isDir){
          createConfirm({
            title: '删除文件夹',
            content: '确定要删除该文件夹吗？',
            iconType: 'warning',
            onOk: async () => {
              const res = await deteleDirDelete({ id: dirId })
              const { data } = res
              if( data.code === 200) {
                searchQuery()
              }
            },
            onCancel: () => {},
          });
          
        }else{
          createConfirm({
            title: '删除文件',
            content: '确定要删除该文件吗？',
            iconType: 'warning',
            onOk: async () => {
              const res = await delSingleFile({ id: fileId })
              const { data = {} } = res
              if( data.code === 200) {
                searchQuery()
              }
            },
            onCancel: () => {},
          });
        }
      }
    break;
  }
}

//权限控制  true: 有权限  false: 无权限 (用在template上)
const btnAuthTemplate = computed(() => (type: string): boolean => {
  const curDirListTemp = dirNavigation.value
  const btnAccess = {
    '上传文件': curDirListTemp?.length > 1 && curDirListTemp[curDirListTemp?.length - 1]?.dirType === '3',  // 非根目录且是用户目录
    '新建文件夹': curDirListTemp?.length > 1 && curDirListTemp[curDirListTemp?.length - 1]?.dirType === '3',
    '移动文件': curDirListTemp?.length > 1,  // 非根目录
  }
  return btnAccess[type] || false
})

//权限控制  true: 有权限  false: 无权限
const btnAuth = (type: string, record?: any): boolean => {
  const curDirListTemp = dirNavigation.value
  const { isDir, directoryType } = record
  const btnAccess = {
    '重命名': curDirListTemp?.length > 1 && (!isDir || isDir && directoryType === '3'),
    '移动': curDirListTemp?.length > 1 && (!isDir || isDir && directoryType === '3'),
    '删除': curDirListTemp?.length > 1 && (!isDir || isDir && directoryType === '3'),
  }
  return btnAccess[type]
}

function createActions(record: EditRecordRow, column: BasicColumn): ActionItem[] {
  return [
    {
      label: '重命名',
      icon: "ant-design:edit-outlined",
      onClick: handleAction.bind(null, '重命名', record),
      ifShow: btnAuth('重命名', record)
    },
    {
      label: '移动',
      icon: "ic:outline-drive-file-move",
      onClick: handleAction.bind(null, '移动', record),
      ifShow: btnAuth('移动', record)
    },
    {
      label: '删除',
      icon: "icon-park-outline:delete",
      onClick: handleAction.bind(null, '删除', record),
      ifShow: btnAuth('删除', record)
    },
  ];
}

// 切换文件夹导航
const clickDir = (index: number) => {
  let navigation =  dirNavigation.value
  navigation = navigation.slice(0, index + 1)
  dirNavigation.value = navigation
  sessionStorage.setItem(DataDirNavigation, JSON.stringify(navigation))
  //console.log("navigation", navigation)
  queryParam.parentId = navigation[navigation.length - 1]?.id
  searchQuery()
}

// 跳转到子文件夹
const openDir = (record) => {
  //console.log("子文件夹--record", record)
  const { dirId, directoryName, directoryType } = record
  dirNavigation.value.push({
    name: directoryName,
    id: dirId,
    dirType: directoryType
  })
  sessionStorage.setItem(DataDirNavigation, JSON.stringify(dirNavigation.value))
  queryParam.parentId = dirId
  searchQuery()
}

const enterSearch = (value) => {
  //console.log("查询文件==value", value)
  queryParam.fileName = value
  searchQuery()
}

const selectChange = (type: string, value?: any) => {
  //console.log("value", value)
  switch(type){
    case "device":
      queryParam.device = value ?? ''
      searchQuery()
      break
    case "fileType":
      queryParam.fileType = value ?? ''
      searchQuery()
      break
  }
}

</script>
<style lang="less" scoped>
/deep/ .jeecg-basic-table-header__toolbar {
  width: auto;
}
/deep/ .cell-content::before {
  content: url('/@/assets/icons/FolderOpenFilled.svg');
  margin-right: 10px;
  vertical-align: middle;
}
/deep/ .cell-content {
  cursor: pointer
}
/deep/ .ant-table-thead>tr>th {
  background: #edf6fb;
  color: #0F699A;
}
/deep/ .ant-table-tbody>tr.ant-table-row:hover>td,
.ant-table-tbody>tr>td.ant-table-cell-row-hover {
  background: #f7fbfc;
}
/deep/ .ant-popover-buttons {
  display: flex;
}
.folderLevelBox {
  display: flex;
  margin-top: 9px;
  margin-bottom: 16px;
  .left {
    width: 84px;
    height: 40px;
    background: linear-gradient(180deg, #E8F3F8 0%, rgba(232, 243, 248, 0) 100%);
    opacity: 0.9;
    border: 1px solid rgba(11, 121, 181, 0.6);
    display: flex;
    align-items: center;
    justify-content: center;
    color: #60A7CE;
    font-weight: 400;
    font-size: 14px;
  }
  .right {
    flex: 1;
    height: 40px;
    display: flex;
    align-items: center;
    margin-right: 18px;
    .rightBox {
      height: 100%;
      padding-left: 12px;
      display: flex;
      align-items: center;
      background: linear-gradient(180deg, #E8F3F8 0%, rgba(232, 243, 248, 0) 100%);
      opacity: 0.8;
      border: 1px solid rgba(11, 121, 181, 0.6);
      .box {
        display: flex;
        align-items: center;
        margin-right: 4px;

        .img {
          display: flex;
          align-items: center;
        }
        .text {
          margin-left: 6px;
          margin-right: 6px;
          color: #666666;
          &.openDir:hover{
            cursor:pointer;
          }
        }
      }

      .box:last-child {
        .anticon-caret-right:last-child {
          display: none;
        }
      }
    }
  }
}
.colFileName{
  .openDir:hover{
    cursor:pointer;
  }
}
.upload {
  background: linear-gradient(315deg, #2997d2 0%, #1880b9 100%);
  box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.16);
  border-radius: 2px;
  color: white;
}
</style>
